package fnord.jovian.tango;

import java.awt.*;
import java.awt.geom.*;
import java.util.Vector;

import fnord.jovian.TheBoard;
import fnord.jovian.TheField;

public class TheMap implements TheObject {

	private TheBoard _board;
	private Ellipse2D.Double _map;
	private TheField _miniField;
	private Vector<TheCardTree> _miniTrees;
	private Vector<Ellipse2D.Double> _miniCircles;
	private int _player, _currentTree, _maskTree = -2, _clickTree = -2;

	private static final double MAPSIZE = 200, CURRENTSIZE = 60;
	private static final Color BACKGROUND = new Color(0,75,0);

	public TheMap(TheBoard board) {
		_board = board;
		_map = new Ellipse2D.Double(0,0,MAPSIZE,MAPSIZE);
		_miniCircles = new Vector<Ellipse2D.Double>();
		_miniTrees = new Vector<TheCardTree>();
		_miniField = new TheField(board,true);
		_miniField.setSize(CURRENTSIZE, CURRENTSIZE);
	}

	@Override
	public void paint(Graphics2D g) {
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(BACKGROUND);
		g.fill(_map);
		g.setColor(new Color(20,20,20));
		g.setStroke(new java.awt.BasicStroke(2));
		g.draw(_map);
		double rotationInc = 0;
		if (!_miniTrees.isEmpty())
			rotationInc = 2.0*Math.PI/(double)(_miniTrees.size());
		for (int j = _player; j < _player + _miniTrees.size(); j++) {
			int i = j % _miniTrees.size();
			_miniTrees.get(i).paint(g);
			if (_currentTree == i) {
				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
				g.setColor(Color.BLACK);
				g.fill(_miniCircles.get(i));
				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));				
			}
			if (_maskTree == i) {
				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
				g.setColor(Color.BLACK);
				g.fill(_miniCircles.get(i));
				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
			}
			g.rotate(rotationInc,_map.getCenterX(),_map.getCenterY());
		}
		_miniField.paint(g);
		if (_currentTree == -1) {
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
			g.setColor(Color.BLACK);
			g.fill(_miniCircles.get(_miniTrees.size()));
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));				
		}
		if (_maskTree == -1) {
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
			g.setColor(Color.BLACK);
			g.fill(_miniCircles.get(_miniTrees.size()));
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
		}
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
	}

	public void setMiniTrees(Vector<TheCardTree> miniTrees, TheField miniField, int player, int current) {
		_miniTrees = miniTrees;
		_miniField = miniField;
		_miniField.setSize(CURRENTSIZE, CURRENTSIZE);
		_miniCircles = new Vector<Ellipse2D.Double>();
		_player = player;
		_currentTree = current;
		setLocation(_map.getX(),_map.getY());
	}

	public double getHeight() {
		return _map.getHeight();
	}

	public double getWidth() {
		return _map.getWidth();
	}

	public double getX() {
		return _map.getX();
	}

	public double getY() {
		return _map.getY();
	}

	public void setLocation(double x, double y) {
		_miniCircles = new Vector<Ellipse2D.Double>();
		_map.setFrame(x,y,_map.getWidth(),_map.getHeight());
		for (int i = 0; i < _miniTrees.size(); i++) {
			_miniTrees.get(i).setLocation(x + (_map.getWidth() - _miniTrees.get(i).getWidth())/2.0,
					y + _map.getHeight() - (CURRENTSIZE + _miniTrees.get(i).getHeight())/2.0);
			_miniCircles.add(new Ellipse2D.Double(x + (_map.getWidth() - CURRENTSIZE)/2.0,
					y + _map.getHeight() - CURRENTSIZE,CURRENTSIZE,CURRENTSIZE));
		}
		_miniField.setLocation(x + (_map.getWidth() - CURRENTSIZE)/2.0,
				y + (_map.getHeight() - CURRENTSIZE)/2.0);
		_miniCircles.add(new Ellipse2D.Double(x + (_map.getWidth() - CURRENTSIZE)/2.0,
				y + (_map.getHeight() - CURRENTSIZE)/2.0,CURRENTSIZE,CURRENTSIZE));
	}

	public void setCurrent(int currentTree, boolean moved) {
		if (_currentTree != currentTree && !moved) {
			if (currentTree == -1) {
				_board.switchTree(2);
			}
			else {
				_board.switchTree(0,currentTree);
			}
		}
		_currentTree = currentTree;
	}

	public void setSize(double w, double h) {
		_map.setFrame(_map.getX(),_map.getY(),w,h);
		setLocation(_map.getX(),_map.getY());
	}

	public boolean contains(Point p) {
		double rotationInc = 0;
		if (!_miniTrees.isEmpty())
			rotationInc = 2.0*Math.PI/(double)(_miniTrees.size());
		for (int j = _player; j < _player + _miniTrees.size(); j++) {
			int i = j % _miniTrees.size();
			java.awt.geom.AffineTransform trans = java.awt.geom.AffineTransform.getRotateInstance(rotationInc*(double)i, _map.getCenterX(), _map.getCenterY());
			java.awt.Shape s = trans.createTransformedShape(_miniCircles.get(i));
			if (s.contains(p)) {
				_maskTree = i;
				return true;
			}
		}
		if (_miniCircles.get(_miniTrees.size()).contains(p)) {
			_maskTree = -1;
			return true;
		}
		_maskTree = -2;
		return false;
	}

	public boolean containsClick(Point p) {
		double rotationInc = 0;
		if (!_miniTrees.isEmpty())
			rotationInc = 2.0*Math.PI/(double)(_miniTrees.size());
		for (int j = _player; j < _player + _miniTrees.size(); j++) {
			int i = j % _miniTrees.size();
			java.awt.geom.AffineTransform trans = java.awt.geom.AffineTransform.getRotateInstance(rotationInc*(double)i, _map.getCenterX(), _map.getCenterY());
			java.awt.Shape s = trans.createTransformedShape(_miniCircles.get(i));
			if (s.contains(p)) {
				_clickTree = i;
				return true;
			}
		}
		if (_miniCircles.get(_miniTrees.size()).contains(p)) {
			_clickTree = -1;
			return true;
		}
		_clickTree = -2;
		return false;
	}

	public boolean containsUp(Point p) {
		double rotationInc = 0;
		if (!_miniTrees.isEmpty())
			rotationInc = 2.0*Math.PI/(double)(_miniTrees.size());
		for (int j = _player; j < _player + _miniTrees.size(); j++) {
			int i = j % _miniTrees.size();
			java.awt.geom.AffineTransform trans = java.awt.geom.AffineTransform.getRotateInstance(rotationInc*(double)i, _map.getCenterX(), _map.getCenterY());
			java.awt.Shape s = trans.createTransformedShape(_miniCircles.get(i));
			if (s.contains(p) && _clickTree == i) {
				setCurrent(i, false);
				return true;
			}
		}
		if (_miniCircles.get(_miniTrees.size()).contains(p) && _clickTree == -1) {
			setCurrent(-1, false);
			return true;
		}
		_clickTree = -2;
		return false;
	}

	public boolean containsDrag(Point p) {
		return false;
	}

	public double getCenterX() {
		return _map.getCenterX();
	}

	public double getCenterY() {
		return _map.getCenterY();
	}

}
